﻿using log4net;
using MaterialTypeRecognition.Shell.Logs;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace MaterialTypeRecognition.Shell.MesServices
{
    public interface IInBoundMesService
    {
        Task<StartResponseMessageDto> PostAsync(StartRequestMessageDto message);
    }

    internal class InBoundMesService : IInBoundMesService
    {
        private readonly ILog _mesLog;

        public InBoundMesService(ILog4NetLoggerFactory factory)
        {
            _mesLog = factory.GetMesLogger();
        }

        private static readonly HttpClient httpClient = new HttpClient();

        public async Task<StartResponseMessageDto> PostAsync(StartRequestMessageDto model)
        {
            if (string.IsNullOrWhiteSpace(model.Url))
            {
                return new StartResponseMessageDto()
                {
                    Success = false,
                    Message = "MesApi 地址为空，请点击主页面“配置按钮”，进入配置页面，在“API 地址”一栏输入 API 地址。"
                };
            }

            _mesLog.Info("本次分类调用api为：" + model.Url ?? "Empty");
            string url = model.Url!;
            string authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{model.UserName}:{model.Password}"));
            string body = @$"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:mif=""http://miFirstOperationForsfc.ws.atlmes.com/"">
   <soapenv:Header/>
   <soapenv:Body>
      <mif:miFirstOperationForsfc>
         <!--Optional:-->
         <MiFirstOperationForsfcRequest>
            <site>{model.Site}</site>
            <resource>{model.Resource}</resource>
            <modeProcessSfc>{model.ModeProcessSfc}</modeProcessSfc>
            <operation>{model.Operation}</operation>
            <activity>{model.Activity}</activity>
            <!--Optional:-->
            <operationRevision>{model.OperationRevision}</operationRevision>
            <!--Optional:-->
            <user>{model.User}</user>
            <!--Optional:-->
            <sfc>{model.Sfc}</sfc>
            <!--Optional:-->
            <processLot>{model.ProcessLot}</processLot>
         </MiFirstOperationForsfcRequest>
      </mif:miFirstOperationForsfc>
   </soapenv:Body>
</soapenv:Envelope>";

            // 打印发送报文。
            _mesLog.Info(body);
            var content = new StringContent(body, Encoding.UTF8, "text/xml");
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authToken);

            try
            {
                HttpResponseMessage responseMessage = await httpClient.PostAsync(url, content);
                string stringMessage = await responseMessage.Content.ReadAsStringAsync();

                // 打印接受报文。
                _mesLog.Info(stringMessage);

                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(stringMessage);

                var codeNode = xmlDocument.SelectSingleNode("//code");
                var messageNode = xmlDocument.SelectSingleNode("//message");

                if (codeNode != null && messageNode != null)
                {
                    if (codeNode.InnerText == "0")
                    {
                        var message = messageNode.InnerText;
                        if (string.IsNullOrWhiteSpace(message) || !message.Any(charItem => charItem > '0' && charItem < '9'))
                        {
                            return new StartResponseMessageDto() { Success = false, Message = $"SFC {model.Sfc} 分类失败，MES不支持极片分类。" };
                        }
                        else
                        {
                            return new StartResponseMessageDto() { Success = true, Message = messageNode.InnerText };
                        }
                    }
                    else
                    {
                        return new StartResponseMessageDto() { Success = false, Message = $"SFC {model.Sfc} 分类失败，错误码：{codeNode.InnerText}" + "Message: " + messageNode.InnerText };
                    }
                }
                else
                {
                    throw new InvalidOperationException("非标准 MES 报文。");
                }

            }
            catch (Exception ex)
            {
                _mesLog.Error(ex);
                return new StartResponseMessageDto() { Success = false, Message = $"SFC {model.Sfc} 分类失败，请查看极片自动分类软件 MES 日志！" };
            }
        }
    }
}